package drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.branch_transaction_end_status_report;

import drds.global_transaction.api.message_codec.Message;
import drds.global_transaction.api.message_codec.request_and_response.transaction.branch_transaction.BranchTransactionRequestMessage;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.Setter;

import java.nio.ByteBuffer;

public abstract class BranchTransactionEndStatusReportRequestMessage extends BranchTransactionRequestMessage
{

	private static final long serialVersionUID = 1L;
	@Setter
	@Getter
	protected String globalTransactionIdWithAddressAndPort;
	@Setter
	@Getter
	protected long branchTransactionId;
	@Setter
	@Getter
	protected String resourceId;
	/**
	 * 可能这个数据足够长
	 */
	@Setter
	@Getter
	protected String applicationData;

	@Override
	public boolean decode(ByteBuf byteBuf)
	{
		int readableBytes = byteBuf.readableBytes();
		// int read = 0;
		int length = byteBuf.readShort();
		if (length > 0)
		{
			if (readableBytes < length)
			{
				return false;
			}
			byte[] bytes = new byte[length];
			byteBuf.readBytes(bytes);
			setGlobalTransactionIdWithAddressAndPort(new String(bytes, Message.UTF8));
			readableBytes -= length;
		}
		this.branchTransactionId = byteBuf.readLong();
		readableBytes -= 8;
		// this.branchType = BranchType.get(in.readByte());
		// leftLength--;

		length = byteBuf.readShort();
		if (length > 0)
		{
			if (readableBytes < length)
			{
				return false;
			}
			byte[] bytes = new byte[length];
			byteBuf.readBytes(bytes);
			setResourceId(new String(bytes, Message.UTF8));
			readableBytes -= length;
		}

		length = byteBuf.readShort();
		if (length > 0)
		{
			if (readableBytes < length)
			{
				return false;
			}
			byte[] bytes = new byte[length];
			byteBuf.readBytes(bytes);
			setApplicationData(new String(bytes, Message.UTF8));
			readableBytes -= length;
		}

		return true;
	}

	@Override
	public byte[] encode()
	{
		ByteBuffer byteBuffer = createByteBuffer();
		// first expand
		byte[] applicationDataBytes = null;
		if (this.applicationData != null)
		{
			applicationDataBytes = applicationData.getBytes(Message.UTF8);
			if (applicationDataBytes.length > 512)
			{
				byteBuffer = ByteBuffer.allocate(applicationDataBytes.length + 1024);
			}
		}
		//
		if (this.globalTransactionIdWithAddressAndPort != null)
		{
			byte[] bytes = globalTransactionIdWithAddressAndPort.getBytes(Message.UTF8);
			byteBuffer.putShort((short) bytes.length);
			if (bytes.length > 0)
			{
				byteBuffer.put(bytes);
			}
		} else
		{
			byteBuffer.putShort((short) 0);
		}
		//
		byteBuffer.putLong(this.branchTransactionId);
		//
		if (this.resourceId != null)
		{
			byte[] bytes = resourceId.getBytes(Message.UTF8);
			byteBuffer.putShort((short) bytes.length);
			if (bytes.length > 0)
			{
				byteBuffer.put(bytes);
			}
		} else
		{
			byteBuffer.putShort((short) 0);
		}
		//
		if (this.applicationData != null)
		{
			byteBuffer.putInt(applicationDataBytes.length);
			if (applicationDataBytes.length > 0)
			{
				byteBuffer.put(applicationDataBytes);
			}
		} else
		{
			byteBuffer.putInt(0);
		}
		//
		byteBuffer.flip();
		byte[] bytes = new byte[byteBuffer.limit()];
		byteBuffer.get(bytes);
		return bytes;
	}
}
